﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using RPCenter.UpdaterService.Helper;
using RPCenter.WindowsAPI;

namespace RPCenter.UpdaterService
{
    public class TownCrier
    {
        readonly Timer _app_timer;
        readonly Timer _timer; 
        private StartSet theM = new StartSet(); 
        public TownCrier()
        { 
            theM = XmlHelper.GetStartConfigXml();
            if (theM == null) { theM = new StartSet(); } 
            //定时检测刷新配置
            _timer = new Timer(theM.GlobalIntervalMin*1000*60) { AutoReset = true };
            _timer.Elapsed += new ElapsedEventHandler(ReloadConfigEvent);
            //每秒执行
            _app_timer = new Timer(1000*60) { AutoReset = true };
            _app_timer.Elapsed += new ElapsedEventHandler(StartApplicationEvent);
            _timer.Start();
            _app_timer.Start();
        }
        public void Start() { _timer.Start(); _app_timer.Start(); }
        public void Stop() { _timer.Stop(); _app_timer.Stop(); }
        /// <summary>
        /// 重载配置文件
        /// </summary>
        /// <param name="source"></param>
        /// <param name="e"></param>
        public void ReloadConfigEvent(object source, ElapsedEventArgs e)
        {
            lock(this)
            {
                bool initAppEvent = false;
                //读取配置 
                StartSet newM = XmlHelper.GetStartConfigXml();
                //时间不一致 重载配置
                if (theM.GlobalIntervalMin != newM.GlobalIntervalMin)
                {
                    initAppEvent = true;
                }
                List<StartNode> duibiNodes = newM.StartNodeInfo;
                List<StartNode> oldNodes = theM.StartNodeInfo;
                //重载配置方法
                foreach (StartNode sn in oldNodes)
                {
                    if (duibiNodes.Where(a=>a.Name==sn.Name&&a.Folder==sn.Folder&&a.ApplicationName==sn.ApplicationName&&a.Type==sn.Type&&a.IntervalMin==sn.IntervalMin&&a.ShowUI==sn.ShowUI).Count()<=0)
                    {
                        initAppEvent = true;
                    }
                    else
                    { 
                        duibiNodes.RemoveAll(a => a.Name == sn.Name && a.Folder == sn.Folder && a.ApplicationName == sn.ApplicationName && a.Type == sn.Type && a.IntervalMin == sn.IntervalMin && a.ShowUI == sn.ShowUI);
                        duibiNodes.Remove(sn);
                    } 
                }
                if (duibiNodes.Count > 0)
                {
                    //有新增
                    initAppEvent = true;
                }
                if (initAppEvent)
                {
                    newM.StartNodeInfo.ForEach(a => a.LastMin = a.IntervalMin);
                    theM = newM; 
                }
                Console.WriteLine("服务配置重启"+initAppEvent);
            }
        } 

        /// <summary>
        /// 重载应用启动计划 （每秒执行）
        /// </summary>
        /// <param name="source"></param>
        /// <param name="e"></param>
        public void StartApplicationEvent(object source, ElapsedEventArgs e)
        {
            lock (this)
            {
                //重载配置方法
                foreach (StartNode sn in theM.StartNodeInfo)
                {
                    if (!(sn.IntervalMin >= 1)
                        || (sn.Type == "exe" && (string.IsNullOrEmpty(sn.ApplicationName) || string.IsNullOrEmpty(sn.Folder)))
                        || (sn.Type == "service" && string.IsNullOrEmpty(sn.ApplicationName)))
                    {
                        //无效数据
                        continue;
                    }
                    sn.LastMin--;
                    if (sn.LastMin <= 0)
                    {
                        sn.LastMin = sn.IntervalMin;
                        //启动
                        if (sn.Type == "exe")
                        {
                            StartExe(sn.Folder, sn.ApplicationName,sn.ShowUI);
                        }
                        else if (sn.Type == "service")
                        {
                            StartStopService(sn.ApplicationName, 1);
                        }
                    }
                    Console.WriteLine(sn.Name+"剩下"+sn.LastMin+"秒！");
                }
                Console.WriteLine("倒计时计算应用时间！");
            }
        } 
        #region 服务启动 停止
        /// <summary>
        /// 服务启动 停止
        /// </summary>
        /// <param name="serviceName"></param>
        /// <param name="theEvent">1启动 2停止</param>
        private void StartStopService(string serviceName, int theEvent)
        {
            ServiceController serviceController1 = new ServiceController();
            serviceController1.ServiceName = serviceName;
            serviceController1.MachineName = ".";
            if (theEvent == 1)
            {
                if (serviceController1.Status != ServiceControllerStatus.Running)
                {
                    Log4netHelper.Info("时间："+DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")+" 服务："+ serviceName + "启动成功\r\n\r\n\r\n\r\n\r\n");
                    serviceController1.Start();
                }
            }
            else
            {
                if (serviceController1.Status == ServiceControllerStatus.Running)
                    serviceController1.Stop();
                Log4netHelper.Info("时间：" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " 服务：" + serviceName + "停止成功\r\n\r\n\r\n\r\n\r\n");
            }
        }
        #endregion

        #region 启动进程、关闭进程、判断进程是否存在
        //启动exe绝对路径
        private void StartExe(string filePath, string fileName, bool ShowUI = false)
        {
            bool isHave = false;
            string proceName = fileName;
            if (fileName.LastIndexOf(".") >= 0)
            {
                proceName= fileName.Substring(0, fileName.LastIndexOf("."));
            }
            Process[] processes  = System.Diagnostics.Process.GetProcessesByName(proceName);
            if (processes.Length > 0) { isHave = true; }

            if (!isHave)
            {
                if (!ShowUI)
                {
                    Process proc = new Process();
                    proc.StartInfo.UseShellExecute = false;//是否使用操作系统外壳程序启动进程 
                    proc.StartInfo.WorkingDirectory = filePath;//启动进程的初始目录
                    proc.StartInfo.FileName = fileName;
                    proc.Start();
                }
                else
                {
                    //服务中启动程序，强制显示程序界面
                    StartExeInService.SimpleStartExe(filePath+fileName);
                }
                Log4netHelper.Info("时间：" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " 应用：" + filePath + fileName + "启动成功\r\n\r\n"); 

            }
            else
            { 
                Log4netHelper.Info("时间：" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " 应用：" + filePath + fileName + "已存在\r\n\r\n");
            }

        }
        #endregion
    }
}
